package com.itlong.cloud.property.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Joiner;
import com.google.zxing.BarcodeFormat;
import com.itlong.cloud.POJO.DTO.property.ElevatorFloorChangeDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyCloudIntercomSaveDTO;
import com.itlong.cloud.POJO.DTO.property.PropertySubscriberHanlerDTO;
import com.itlong.cloud.POJO.DTO.smartcard.SmartCardSyncDataPullDTO;
import com.itlong.cloud.POJO.PO.*;
import com.itlong.cloud.POJO.VO.property.EquipAddressGetVO;
import com.itlong.cloud.POJO.VO.property.PropertyEquipUpdateVO;
import com.itlong.cloud.POJO.VO.property.PropertyUserCacheVO;
import com.itlong.cloud.POJO.VO.property.PropertyGetElevatorNameAndDeviceUniqueVO;
import com.itlong.cloud.POJO.VO.property.PropertyGetFloorByDeviceUniqueVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.datasource.dao.ISubscriberDao;
import com.itlong.cloud.enumerate.*;
import com.itlong.cloud.operate.dao.IOperateSipClusterDao;
import com.itlong.cloud.property.dao.*;
import com.itlong.cloud.property.service.IPropertyAddEquipService;
import com.itlong.cloud.property.service.IPropertyDeviceAuthService;
import com.itlong.cloud.propertyapp.dao.IPropertyAppDeviceDao;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.smartcard.dao.ISmartCardFaceDao;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.encrypt.Md5;
import com.itlong.cloud.utils.encrypt.TencentUtil;
import com.itlong.cloud.utils.file.PemFileUtil;
import com.itlong.cloud.utils.file.UploadFileUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.picture.LogoConfig;
import com.itlong.cloud.utils.picture.QrcodeUtils;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * <desc>
 * 设备添加和更新实现类
 * </desc>
 *
 * @createDate 2017/10/16
 */
@Service
@RefreshScope
public class PropertyAddEquipServiceImpl implements IPropertyAddEquipService {

    private static final Logger LOG = LoggerFactory.getLogger(PropertyEquipServiceImpl.class);

    //物业电梯持久层接口
    @Autowired
    private IPropertyElevatorDao iPropertyElevatorDao;

    //物业电梯归属地持久层接口
    @Autowired
    private IDeviceElevatorBridgeInfoDao iDeviceElevatorBridgeInfoDao;

    //物业门禁持久层接口
    @Autowired
    private IDeviceEntranceInfoDao iDeviceEntranceInfoDao;

    //物业电梯归属地持久层接口
    @Autowired
    private IDeviceEntranceBridgeInfoDao iDeviceEntranceBridgeInfoDao;

    //物业云对讲持久层接口
    @Autowired
    private IDeviceCloudIntercomInfoDao iDeviceCloudIntercomInfoDao;

    //物业云对讲归属地持久层接口
    @Autowired
    private IDeviceCloudIntercomBridgeInfoDao iDeviceCloudIntercomBridgeInfoDao;

    //RabbitMQ消息队列生产者
    @Autowired
    private MessageSender messageSender;

    //sip数据持久层
    @Autowired
    ISubscriberDao iSubscriberDao;

    //si集群持久层
    @Autowired
    IOperateSipClusterDao iOperateSipClusterDao;

    @Autowired
    IPropertyDeviceAuthService ipropertyDeviceAuthService;

    @Autowired
    IDeviceElevatorFloorConfigDao floorConfigDao;

    @Autowired
    ITimeTaskAuthDeviceAddressInfoDao iTimeTaskAuthDeviceAddressInfoDao;

    @Autowired
    IDeviceAddressUserInfoServiceDao iDeviceAddressUserInfoServiceDao;

    @Autowired
    ISmartCardFaceDao iSmartCardFaceDao;

    @Autowired
    private IPropertyEquipDao iPropertyEquipDao;

    @Autowired
    IPropertyAppDeviceDao iPropertyAppDeviceDao;

    @Autowired
    RedisService<PropertyUserCacheVO> redisService;

    @Autowired
    IDeviceCloudControllerDao iDeviceCloudControllerDao;

    private static ExecutorService importAddressFixedThreadPool = Executors.newFixedThreadPool(20); // 处理门禁设备和角色组关系线程池


    @Value("${" + PlatformConstants.FILE_FTP_HOST + "}")
    public String FILE_FTP_HOST;

    @Value("${" + PlatformConstants.FILE_FTP_PORT + "}")
    public String FILE_FTP_PORT;

    @Value("${" + PlatformConstants.FILE_FTP_USERNAME + "}")
    public String FILE_FTP_USERNAME;

    @Value("${" + PlatformConstants.FILE_FTP_PASSWORD + "}")
    public String FILE_FTP_PASSWORD;

    @Value("${" + PlatformConstants.FILE_ACCESS_URL + "}")
    public String FILE_ACCESS_URL;

    @Value("${" + PlatformConstants.TENCENT_STATIC_FILE_PATH + "}")
    public String TENCENT_STATIC_FILE_PATH;

    @Value("${" + PlatformConstants.DEVICE_SIP_ACCOUNT_PREFIX + "}")
    public String DEVICE_SIP_ACCOUNT_PREFIX;

    /**
     * <desc>
     *      获取电梯楼层对应表
     * </desc>
     *
     * @param deviceUnique
     * @return
     * @author Jiaqi.X
     * @createDate 2020/03/27
     */
    @Override
    public List<PropertyGetFloorByDeviceUniqueVO> getFloorByDeviceUnique(String deviceUnique) {
        return iPropertyEquipDao.getFloorByDeviceUnique(deviceUnique);
    }

    /**
     * <desc>
     *      根据项目id获取云电梯列表
     * </desc>
     *
     * @param projectId
     * @return
     * @author Jiaqi.X
     * @createDate 2020/03/27
     */
    @Override
    public List<PropertyGetElevatorNameAndDeviceUniqueVO> getElevatorByProjectId(String projectId,String unitId,String floorNum) {
        String[] unitIds = StringHandlerUtil.splitString(unitId);
        if(unitIds.length == 0){
            unitIds = null;
        }
        return iPropertyEquipDao.getElevatorByProjectId(projectId,unitIds,floorNum);
    }

    /**
     * <desc>
     *      通过线程添加单个设备及其归属信息
     * <desc/>
     * @param   propertyEquipSaveDTO    物业设备数据转换对象
     * @return
     * @author zhangs
     * @createDate 2018/1/5
     */
    public void insertEquip(PropertyCloudIntercomSaveDTO propertyEquipSaveDTO) throws Exception {
        Integer deviceType = propertyEquipSaveDTO.getDeviceType();
        String deviceId = String.format("%04d", Integer.parseInt(propertyEquipSaveDTO.getDeviceId()));
        propertyEquipSaveDTO.setDeviceId(deviceId);
        List<DeviceBusinessChangeLogPO> deviceBusinessChangeLogPOS = null;
        String deviceUnique = "";
        switch (PropertyEquipTypeEnum.getByEquipType(deviceType)) {
            case ELEVATOR:
                this.addElevator(propertyEquipSaveDTO);
                deviceUnique = String.format("%s1%s",propertyEquipSaveDTO.getProjectId(),deviceId);
                break;
            case ENTRANCE:
                this.addEntrance(propertyEquipSaveDTO);
                deviceUnique = String.format("%s2%s",propertyEquipSaveDTO.getProjectId(),deviceId);
                break;
            case CLOUD_INTERCOM:
                deviceBusinessChangeLogPOS = this.addCloudIntercom(propertyEquipSaveDTO);
                deviceUnique = String.format("%s3%s",propertyEquipSaveDTO.getProjectId(),deviceId);
                break;
            default:
                return;
        }
        //新增设备，处理项目下的物业账号有排序的情况
        List<Map<String,Object>> deviceOrderList = iPropertyAppDeviceDao.getPropertyAppUserDeviceOrderInfo(propertyEquipSaveDTO.getProjectId());
        if(deviceOrderList!=null){
            for(Map<String,Object> map : deviceOrderList){
                String userId = map.get("userId").toString();
                String deviceOrder = String.format("%s,%s",map.get("deviceOrder").toString(),deviceUnique).replace(",,",",");
                iPropertyAppDeviceDao.updatePropertyRoleProject(userId, propertyEquipSaveDTO.getProjectId(), "", "",deviceOrder);
                //清除获取设备列表缓存
                redisService.del(RedisConstant.REDIS_PROPERTY_APP_USER_DEVICE_CACHE + userId + propertyEquipSaveDTO.getProjectId());
            }
        }
        //设备地址变更，存储变更后的地址信息，等待定时任务刷新权限
        if(propertyEquipSaveDTO.getElevatorType()== null || (propertyEquipSaveDTO.getElevatorType()!=null && propertyEquipSaveDTO.getElevatorType() != PropertyEquipTypeEnum.BLUETOOTH_CALL.getType())) {
            TimeTaskAuthDeviceAddressInfoPO deviceAddrPO = propertyEquipSaveDTO.getTimeTaskAuthDeviceAddressInfoPO();
            if (deviceAddrPO != null) {
                iTimeTaskAuthDeviceAddressInfoDao.save(SqlUtil.durableData(deviceAddrPO, PlatformConstants.TABLE_SAVE));
            }
            // 推送云对讲、云电梯重启指令
            if (deviceBusinessChangeLogPOS != null && !deviceBusinessChangeLogPOS.isEmpty()) {
                this.pushCloudIntercom(deviceBusinessChangeLogPOS);
            }
        }
    }

    /**
     * <desc>
     *      添加单个电梯及其归属信息
     * <desc/>
     *
     * @param propertyEquipSaveDTO 物业设备数据传输对象
     * @return PropertyEquipUpdateVO 物业设备保存VO
     * @author Biao.R
     * @createDate 2017/9/22
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void addElevator(PropertyCloudIntercomSaveDTO propertyEquipSaveDTO) throws Exception {
        //添加电梯信息表
        Date currentTime = new Date();
        DeviceElevatorInfoPO deviceElevatorInfoPO = new DeviceElevatorInfoPO();
        BeanUtils.copyProperties(propertyEquipSaveDTO, deviceElevatorInfoPO);

        String projectId = propertyEquipSaveDTO.getProjectId();
        deviceElevatorInfoPO.setCreateTime(currentTime);
        Integer status = propertyEquipSaveDTO.getStatus();
        deviceElevatorInfoPO.setStatus(status == null ? DataStatusEnum.NORMAL.getType() : status);
        deviceElevatorInfoPO.setOpenThreshold(PlatformConstants.EQUIP_BLUETOOTH_OPEN_THRESHOLD);
        Integer elevatorType = propertyEquipSaveDTO.getElevatorType();
        //此处判断所添加的设备是云电梯的情况
        List<DeviceBusinessElevatorChangeLogPO> deviceBusinessElevatorChangeLogPOs = new ArrayList<>();
        if(elevatorType == PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType()){
            deviceElevatorInfoPO.setElevatorType(elevatorType);
            deviceElevatorInfoPO.setCommonFloor(propertyEquipSaveDTO.getCommonFloor());
            deviceElevatorInfoPO.setIsBluetoothElevator(propertyEquipSaveDTO.getIsBluetoothElevator());
            deviceElevatorInfoPO.setToken(propertyEquipSaveDTO.getToken());
            JSONObject jsonObject=new JSONObject();
            jsonObject.put("sn",deviceElevatorInfoPO.getSn());
            jsonObject.put("deviceUnique",deviceElevatorInfoPO.getDeviceUnique());
            jsonObject.put("projectId",projectId);
            deviceBusinessElevatorChangeLogPOs.add(new DeviceBusinessElevatorChangeLogPO(projectId,CloudElevatorChangeBusinessEnum.PUSH_DEVICE_PROJECT,jsonObject.toJSONString()));
        }
        if(elevatorType == PropertyEquipTypeEnum.BLUETOOTH_ELEVATOR.getType()){
            deviceElevatorInfoPO.setElevatorType(elevatorType);
        }
        deviceElevatorInfoPO.setIotProductId(iPropertyEquipDao.getIotProductId(1,propertyEquipSaveDTO.getProjectId()));
        //添加电梯归属信息表
        String unitIds = propertyEquipSaveDTO.getUnitIds();
        String buildIds = propertyEquipSaveDTO.getBuildIds();
        List<Map<String, Object>> saveDeviceElevatorBridgeInfoPOList = new ArrayList<>();
        if (null != buildIds && null != unitIds) {
            String[] unitIdArr = unitIds.split(",");
            for (String unitId : unitIdArr) {
                DeviceElevatorBridgeInfoPO deviceElevatorBridgeInfoPO = new DeviceElevatorBridgeInfoPO(deviceElevatorInfoPO.getDeviceUnique(), projectId, buildIds, unitId);
                deviceElevatorBridgeInfoPO.setCreateTime(currentTime);
                Map<String, Object> map = SqlUtil.durableData(deviceElevatorBridgeInfoPO, PlatformConstants.TABLE_SAVE);
                saveDeviceElevatorBridgeInfoPOList.add(map);

            }
        }

        if (saveDeviceElevatorBridgeInfoPOList.size() > 0  && propertyEquipSaveDTO.getElevatorType()!=PropertyEquipTypeEnum.BLUETOOTH_CALL.getType()) {
            deviceElevatorInfoPO.setFloorNo(propertyEquipSaveDTO.getFloorNo());
            deviceElevatorInfoPO.setFloorNoMax(propertyEquipSaveDTO.getFloorNoMax());
            //添加楼层映射表
            if(propertyEquipSaveDTO.getElevatorType()!=PropertyEquipTypeEnum.BLUETOOTH_CALL.getType()) {
                //添加楼层映射表
                this.addElevatorFloor(deviceElevatorInfoPO);
                deviceElevatorInfoPO.setFloorNo(1);
                deviceElevatorInfoPO.setFloorNoMax(propertyEquipSaveDTO.getFloorNoMax() < 0 && propertyEquipSaveDTO.getFloorNoMax() == -1 ?
                                Math.abs(propertyEquipSaveDTO.getFloorNo()) :
                                propertyEquipSaveDTO.getFloorNoMax() < 0 && propertyEquipSaveDTO.getFloorNoMax() != -1 ?
                                        Math.abs(propertyEquipSaveDTO.getFloorNo()) - Math.abs(propertyEquipSaveDTO.getFloorNo() + 1) :
                                        propertyEquipSaveDTO.getFloorNo() < 0 ?
                                                Math.abs(propertyEquipSaveDTO.getFloorNo()) + propertyEquipSaveDTO.getFloorNoMax() :
                                                propertyEquipSaveDTO.getFloorNo() == 1 ? propertyEquipSaveDTO.getFloorNoMax() :
                                                        propertyEquipSaveDTO.getFloorNoMax() - propertyEquipSaveDTO.getFloorNo() + 1
                );
            }
        }
        if(propertyEquipSaveDTO.getFloorNums()!=null){
            deviceElevatorInfoPO.setFloorNum(Integer.valueOf(propertyEquipSaveDTO.getFloorNums()));
        }
        iPropertyElevatorDao.save(SqlUtil.durableData(deviceElevatorInfoPO, PlatformConstants.TABLE_SAVE));
        iDeviceElevatorBridgeInfoDao.batchSave(saveDeviceElevatorBridgeInfoPOList);
        if(elevatorType == PropertyEquipTypeEnum.BLUETOOTH_CALL.getType()){
            //清空已绑定数据
            iPropertyEquipDao.deleteBluetoothCallRelation(deviceElevatorInfoPO.getDeviceUnique());
            //蓝牙外呼设备
            if(StringUtils.isNotBlank(propertyEquipSaveDTO.getElevatorDeviceUniques())){
                String[] elevators = StringHandlerUtil.splitString(propertyEquipSaveDTO.getElevatorDeviceUniques());
                for(String elevator : elevators){
                    BluetoothCallElevatorRelationPO call = new BluetoothCallElevatorRelationPO();
                    call.setElevatorDeviceUnique(elevator);
                    call.setDeviceUnique(deviceElevatorInfoPO.getDeviceUnique());
                    call.setRelationId(LogicIdUtil.bussinessId());
                    call.setNaturalFloor(iPropertyEquipDao.getNaturalFloorByFloorNum(propertyEquipSaveDTO.getFloorNums().toString(),call.getElevatorDeviceUnique()));
                    iPropertyEquipDao.save(SqlUtil.durableData(call,PlatformConstants.TABLE_SAVE));
                }
            }
        }

        //若添加为云电梯，同查看临时升级表是否有该条数据，若有则删除，并向电梯推送重启指令
        if(propertyEquipSaveDTO.getElevatorType()==PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType() &&
            iPropertyEquipDao.isExistInSpecialElevator(propertyEquipSaveDTO.getDeviceUnique())>0){
            iPropertyEquipDao.deleteSpecialElevatorByDeviceUnique(propertyEquipSaveDTO.getDeviceUnique());
            List<DeviceBusinessElevatorChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
            JSONArray jsonArrayCloudElevator = new JSONArray();
            JSONObject jsonObjectCloudElevator = new JSONObject();
            jsonObjectCloudElevator.put("deviceUnique", propertyEquipSaveDTO.getDeviceUnique());
            jsonObjectCloudElevator.put("projectId", projectId);
            jsonObjectCloudElevator.put("sn", deviceElevatorInfoPO.getSn());
            jsonArrayCloudElevator.add(jsonObjectCloudElevator);
            //向设备推送设备云电梯指令
            if (!jsonArrayCloudElevator.isEmpty()) {
                DeviceBusinessElevatorChangeLogPO elevatorChangeLogPO = new DeviceBusinessElevatorChangeLogPO(projectId, CloudElevatorChangeBusinessEnum.PUSH_DEVICE_INFO,jsonArrayCloudElevator.toJSONString());
                deviceBusinessChangeLogPOS.add(elevatorChangeLogPO);
                //推送云电梯重启指令
                if(deviceBusinessChangeLogPOS != null && !deviceBusinessChangeLogPOS.isEmpty()){
                    this.pushElevator(deviceBusinessChangeLogPOS);
                    deviceBusinessElevatorChangeLogPOs = new ArrayList<>();
                }
            }
        }


        if(propertyEquipSaveDTO.getElevatorType() != PropertyEquipTypeEnum.BLUETOOTH_CALL.getType()) {
            //推送数据给一卡通
            List<DeviceElevatorInfoPO> deviceInfoPOS = new ArrayList();
            deviceInfoPOS.add(deviceElevatorInfoPO);
            //发送数据
            prepareEquipInfoForSyncToSmartCard(projectId, JSON.toJSONString(deviceInfoPOS), SmartCardSyncDataOperTypeEnum.ADD);
            //推送云电梯业务指令
            if (deviceBusinessElevatorChangeLogPOs.size() > 0) {
                this.pushElevator(deviceBusinessElevatorChangeLogPOs);
            }
        }
    }


    /**
     * <desc>
     *      生成电梯楼层映射表,仅供测试使用
     * <desc/>
     *
     * @param deviceElevatorInfoPO 电梯实体对象
     * @author Biao.R
     * @createDate 2017/11/27
     */
    private void addElevatorFloor(DeviceElevatorInfoPO deviceElevatorInfoPO) throws Exception {
        Integer floorNo = deviceElevatorInfoPO.getFloorNo();
        Integer floorMax = deviceElevatorInfoPO.getFloorNoMax();
        Integer negative = 0+floorNo;
        String deviceUnique = StringHandlerUtil.getProjectIdByDeviceUnique(deviceElevatorInfoPO.getDeviceUnique())+"1"+StringHandlerUtil.getDeviceIdByDeviceUnique(deviceElevatorInfoPO.getDeviceUnique());
        Integer naturalFloor = 1;
        Integer logicalFloor = floorNo;
        Integer terminalFloor = 1;
        Integer detectFloor = 1;
        Integer terminalNumIntercom = 1;
        /*根据设备唯一码查询电梯楼层映射表是否有此唯一码的楼层映射信息，如没有则添加，如有则进行先删除后添加
        更新楼层映射表：物业只关注楼层映射表中的floorNum*/
        Map<String, Object> params = new HashMap<>();
        params.put("deviceUnique", deviceUnique);
        List<DeviceElevatorFloorConfigPO> floorConfigList = floorConfigDao.getByNaturalFloors(params);
        List<DeviceElevatorFloorConfigPO> configPOList = null;
        if(floorConfigList!=null && !floorConfigList.isEmpty()){
            configPOList = floorConfigDao.getFloorConfigIdList(deviceUnique);
        }
        //删除当前楼层对应表
        floorConfigDao.deleteFloorConfig(deviceUnique);
        //生成楼层对应表
        List<DeviceElevatorFloorConfigPO> floorConfigPOList = new ArrayList<>();
        for (int i = 1; i <= PlatformConstants.MAX_ELEVATOR_FLOORNUM; i++) {
            //负楼层在后
            floorNo = (i==1 && negative < 0) || floorNo == 0 ? 1 : floorNo;
            DeviceElevatorFloorConfigPO floorConfigPO = new DeviceElevatorFloorConfigPO(floorNo, deviceUnique, (naturalFloor++).toString());
            if(floorNo > floorMax && negative < 0){
                floorNo = deviceElevatorInfoPO.getFloorNo();
                floorConfigPO.setFloorNum(floorNo);
            }
            if(i > 1 && negative < 0 && floorNo == 1){
                floorNo = floorMax+1;
                negative = 1;
                floorConfigPO.setFloorNum(floorNo);
            }
            floorConfigPO.setLogicalFloor((floorNo).toString());
            floorConfigPO.setTerminalFloor((terminalFloor++).toString());
            floorConfigPO.setDetectFloor((floorNo).toString());
            floorConfigPO.setTerminalNumIntercom((terminalNumIntercom++).toString());
            floorConfigPO.setStatus(DataStatusEnum.NORMAL.getType());
            floorConfigPO.setCreateTime(new Date());
            floorConfigPOList.add(floorConfigPO);
            floorNo++;
        }
        floorConfigDao.saveBatch(floorConfigPOList);
        if(floorConfigList !=null && !floorConfigList.isEmpty()){
            Map<String,Object> oldFloors = new HashMap<>();
            Map<String,Object> newFloors = new HashMap<>();
            for(DeviceElevatorFloorConfigPO configPO : configPOList){
                oldFloors.put(configPO.getNaturalFloor(),configPO.getFloorNum());
            }
            for(DeviceElevatorFloorConfigPO floorInfoDTO : floorConfigPOList){
                newFloors.put(floorInfoDTO.getFloorNum().toString(),floorInfoDTO.getNaturalFloor());
            }
            ElevatorFloorChangeDTO changeDTO = new ElevatorFloorChangeDTO();
            changeDTO.setProjectId(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique));
            changeDTO.setDeviceUnique(deviceUnique);
            changeDTO.setOldFloors(oldFloors);
            changeDTO.setNewFloors(newFloors);

            Map<String, Object> map = new HashMap<>();
            map.put("elevator", changeDTO);
            messageSender.send(
                    RabbitMQConstant.RABBITMQ_CHANGE_USER_ELEVATOR_FLOOR_AUTH_QUEUE,
                    JSON.toJSONString(map),
                    RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CHANGE_USER_ELEVATOR_FLOOR_AUTH_KEY
            );
        }
        //推送数据给一卡通
        prepareEquipFloorRelationDataInfoForSyncToSmartCard(deviceElevatorInfoPO.getProjectId(), JSON.toJSONString(floorConfigPOList), SmartCardSyncDataOperTypeEnum.ADD);
    }


    /**
     * <desc>
     *      添加单个门禁及其归属信息
     * <desc/>
     *
     * @param propertyEquipSaveDTO 物业设备数据传输对象
     * @return PropertyEquipUpdateVO 物业设备保存VO
     * @author Biao.R
     * @createDate 2017/9/22
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void addEntrance(PropertyCloudIntercomSaveDTO propertyEquipSaveDTO) throws Exception {
        //添加门禁信息表
        Date currentTime = new Date();
        DeviceEntranceInfoPO deviceEntranceInfoPO = new DeviceEntranceInfoPO();
        BeanUtils.copyProperties(propertyEquipSaveDTO, deviceEntranceInfoPO);
        String projectId = propertyEquipSaveDTO.getProjectId();
        deviceEntranceInfoPO.setCreateTime(currentTime);
        Integer status = propertyEquipSaveDTO.getStatus();
        deviceEntranceInfoPO.setStatus(status == null ? DataStatusEnum.NORMAL.getType() : status);
        deviceEntranceInfoPO.setOpenThreshold(PlatformConstants.EQUIP_BLUETOOTH_OPEN_THRESHOLD);
        if(PropertyEquipTypeEnum.CLOUD_ENTRANCE_DEVICE.getType()==propertyEquipSaveDTO.getEntranceCategory()
                || PropertyEquipTypeEnum.CLOUD_WIPPEN_DEVICE.getType()==propertyEquipSaveDTO.getEntranceCategory()
                || PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType()==propertyEquipSaveDTO.getEntranceCategory()
                || PropertyEquipTypeEnum.CLOUD_UNIBODY_ENTRANCE_DEVICE.getType()==propertyEquipSaveDTO.getEntranceCategory()){
            deviceEntranceInfoPO.setBindDeviceGroup(propertyEquipSaveDTO.getSn());
        }
        deviceEntranceInfoPO.setIotProductId(iPropertyEquipDao.getIotProductId(2,propertyEquipSaveDTO.getProjectId()));
        deviceEntranceInfoPO.setElevatorDeviceUnique(propertyEquipSaveDTO.getElevatorDeviceUnique());
        deviceEntranceInfoPO.setElevatorFloor((propertyEquipSaveDTO.getElevatorFloor()));
        List<Map<String, Object>> saveEntranceAddrList = new ArrayList<>();
        //添加门禁归属信息表
        if(propertyEquipSaveDTO.getEntranceType() != EntranceTypeEnum.COMMON_ENTRANCE.getType()){
            String unitIds = propertyEquipSaveDTO.getUnitIds();
            String[] buildIdArr = propertyEquipSaveDTO.getBuildIds().split(",");
            if (StringUtils.isNotEmpty(unitIds) || buildIdArr.length == 1) {
                //门禁归属于一栋多单元
                if (StringUtils.isBlank(unitIds)) {
                    unitIds = iDeviceEntranceBridgeInfoDao.getUnitsByBuild(buildIdArr[0]);
                }
                String[] unitIdArr = unitIds.split(",");
                for (String unitId : unitIdArr) {
                    DeviceEntranceBridgeInfoPO deviceEntranceBridgeInfoPO = new DeviceEntranceBridgeInfoPO(deviceEntranceInfoPO.getDeviceUnique(), projectId, buildIdArr[0], unitId);
                    deviceEntranceBridgeInfoPO.setCreateTime(currentTime);
                    Map<String, Object> map = SqlUtil.durableData(deviceEntranceBridgeInfoPO, PlatformConstants.TABLE_SAVE);
                    saveEntranceAddrList.add(map);
                }
            } else {
                //门禁归属于多栋
                for (String buildId : buildIdArr) {
                    DeviceEntranceBridgeInfoPO deviceEntranceBridgeInfoPO = new DeviceEntranceBridgeInfoPO(deviceEntranceInfoPO.getDeviceUnique(), projectId, buildId, null);
                    deviceEntranceBridgeInfoPO.setCreateTime(currentTime);
                    Map<String, Object> map = SqlUtil.durableData(deviceEntranceBridgeInfoPO, PlatformConstants.TABLE_SAVE);
                    saveEntranceAddrList.add(map);
                }
            }
        }
        //保存该门禁所支持功能类型信息
        if(StringUtils.isNotEmpty(propertyEquipSaveDTO.getSupportFunction())){
            String[] strArr = propertyEquipSaveDTO.getSupportFunction().split(",");
            if(propertyEquipSaveDTO.getSupportFunction().contains("6")){
                deviceEntranceInfoPO.setIsFaceRecognition(1);
            }
            List<Map<String, Object>> saveEntranceFunctionList = new ArrayList<>();
            for(String str : strArr){
                DeviceEntranceFunctionInfoPO deviceEntranceFunctionInfo = new DeviceEntranceFunctionInfoPO();
                deviceEntranceFunctionInfo.setDeviceUnique(propertyEquipSaveDTO.getDeviceUnique());
                deviceEntranceFunctionInfo.setFunctionType(Integer.parseInt(str));
                deviceEntranceFunctionInfo.setFunctionTypeName(EntranceFunctionEnum.getDescription(Integer.parseInt(str)));
                deviceEntranceFunctionInfo.setStatus(DataStatusEnum.NORMAL.getType());
                deviceEntranceFunctionInfo.setCreateTime(new Date());
                deviceEntranceFunctionInfo.setUpdateTime(new Date());
                saveEntranceFunctionList.add(SqlUtil.durableData(deviceEntranceFunctionInfo,PlatformConstants.TABLE_SAVE));
            }
            if(!saveEntranceFunctionList.isEmpty()){
                iDeviceEntranceBridgeInfoDao.batchSaveFunction(saveEntranceFunctionList);
            }
        }

        iDeviceEntranceInfoDao.save(SqlUtil.durableData(deviceEntranceInfoPO, PlatformConstants.TABLE_SAVE));
        if (!saveEntranceAddrList.isEmpty()) {
            iDeviceEntranceBridgeInfoDao.batchSave(saveEntranceAddrList);
        }

        //若添加为云门禁、云联动器及临时升级表是否有该条数据，若有则删除，并推送指令
        if((propertyEquipSaveDTO.getEntranceCategory()==PropertyEquipTypeEnum.CLOUD_ENTRANCE_DEVICE.getType()
                || propertyEquipSaveDTO.getEntranceCategory()==PropertyEquipTypeEnum.CLOUD_WIPPEN_DEVICE.getType()
                || propertyEquipSaveDTO.getEntranceCategory()==PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType())
                && iPropertyEquipDao.isExistInSpecialEntrance(propertyEquipSaveDTO.getDeviceUnique())>0){
            iPropertyEquipDao.deleteSpecialEntranceByDeviceUnique(propertyEquipSaveDTO.getDeviceUnique());
            List<DeviceBusinessEntranceChangeLogPO> deviceBusinessEntranceChangeLogPOS = new ArrayList<>();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("deviceUnique", deviceEntranceInfoPO.getDeviceUnique());
            jsonObject.put("projectId", projectId);
            jsonObject.put("sn", deviceEntranceInfoPO.getSn());
            deviceBusinessEntranceChangeLogPOS.add(new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_DEVICE_ONE, jsonObject, projectId));
            if (deviceBusinessEntranceChangeLogPOS != null && !deviceBusinessEntranceChangeLogPOS.isEmpty() &&
                    propertyEquipSaveDTO.getEntranceCategory()!=PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType()) {
                this.pushEntrance(deviceBusinessEntranceChangeLogPOS);
            }
        }

        //推送数据给一卡通
        List<DeviceEntranceInfoPO> deviceInfoPOS = new ArrayList();
        deviceInfoPOS.add(deviceEntranceInfoPO);
        //发送数据
        prepareEquipInfoForSyncToSmartCard(projectId, JSON.toJSONString(deviceInfoPOS), SmartCardSyncDataOperTypeEnum.ADD);

    }


    /**
     * <desc>
     *      添加单个云对讲及其归属信息
     * <desc/>
     *
     * @param propertyEquipSaveDTO 物业设备数据传输对象
     * @return PropertyEquipUpdateVO 物业设备保存VO
     * @author Biao.R
     * @createDate 2017/9/22
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<DeviceBusinessChangeLogPO> addCloudIntercom(PropertyCloudIntercomSaveDTO propertyEquipSaveDTO) throws Exception {

        PropertyEquipUpdateVO saveVO = new PropertyEquipUpdateVO();
        //添加云对讲信息表
        Date currentTime = new Date();
        DeviceCloudIntercomInfoPO deviceCloudIntercomInfoPO = new DeviceCloudIntercomInfoPO();
        BeanUtils.copyProperties(propertyEquipSaveDTO, deviceCloudIntercomInfoPO);
        Integer status = propertyEquipSaveDTO.getStatus();
        deviceCloudIntercomInfoPO.setStatus(status == null ? DataStatusEnum.NORMAL.getType() : status);
        String projectId = propertyEquipSaveDTO.getProjectId();
        String sn = deviceCloudIntercomInfoPO.getSn();
        deviceCloudIntercomInfoPO.setSmartType(propertyEquipSaveDTO.getSmartType());
        deviceCloudIntercomInfoPO.setCreateTime(currentTime);
        //添加云对讲归属信息表
        List<Map<String, Object>> equipAddrList = new ArrayList<>();
        String[] buildIdArr = propertyEquipSaveDTO.getBuildIds().split(",");
        String unitIds = propertyEquipSaveDTO.getUnitIds();
        if (StringUtils.isNotEmpty(unitIds)) {
            if (buildIdArr.length == 1 && (PropertyEquipTypeEnum.CLOUD_INTERCOM_ENTRANCE.getType()).equals(propertyEquipSaveDTO.getSmartType())) {

                String[] unitIdArr = unitIds.split(",");
                //云对讲归属于一栋多单元，门口机
                for (String unitId : unitIdArr) {
                    DeviceCloudIntercomBridgeInfoPO dcciniPO = new DeviceCloudIntercomBridgeInfoPO(deviceCloudIntercomInfoPO.getDeviceUnique(), projectId, buildIdArr[0], unitId);
                    dcciniPO.setCreateTime(currentTime);
                    Map<String, Object> map = SqlUtil.durableData(dcciniPO, PlatformConstants.TABLE_SAVE);
                    equipAddrList.add(map);
                }

            }
        } else {
            if (buildIdArr.length > 0) {
                //云对讲归属于多栋，根据门口机和围墙机分别处理
                for (String buildId : buildIdArr) {
                    DeviceCloudIntercomBridgeInfoPO dcciniPO = new DeviceCloudIntercomBridgeInfoPO(deviceCloudIntercomInfoPO.getDeviceUnique(), projectId, buildId, null);
                    dcciniPO.setCreateTime(currentTime);
                    Map<String, Object> map = SqlUtil.durableData(dcciniPO, PlatformConstants.TABLE_SAVE);
                    equipAddrList.add(map);
                }
            }
        }

        deviceCloudIntercomInfoPO.setSipAccount(DEVICE_SIP_ACCOUNT_PREFIX+sn);
        deviceCloudIntercomInfoPO.setSipPsd(sn);
        /*//添加License
        String license = this.addLicense(propertyEquipSaveDTO);
        deviceCloudIntercomInfoPO.setLicense(license);
        deviceCloudIntercomInfoPO.setMd5(Md5.En(license));*/
        //添加二维码信息
//        String qrCodeSavePath = this.addQrCode(deviceCloudIntercomInfoPO);
//        deviceCloudIntercomInfoPO.setQrCode(qrCodeSavePath);
        Integer saveCloudIntercom = 0;
        if (equipAddrList.size() > 0) {
            saveCloudIntercom = iDeviceCloudIntercomInfoDao.save(SqlUtil.durableData(deviceCloudIntercomInfoPO, PlatformConstants.TABLE_SAVE));
            iDeviceCloudIntercomBridgeInfoDao.batchSave(equipAddrList);
        }

        //保存sip信息
        PropertySubscriberHanlerDTO subscriberHanlerDTO = new PropertySubscriberHanlerDTO(projectId,sn, sn,null);
        JSONObject js = new JSONObject();
        js.put("data",subscriberHanlerDTO);
        messageSender.send(RabbitMQConstant.RABBITMQ_SAVE_OR_UPDATE_SIP_QUEUE, JsonUtil.toJSON(js), RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                RabbitMQConstant.RABBITMQ_SAVE_OR_UPDATE_SIP_KEY);

        //推送设备云对讲重启指令
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("projectId", projectId);
        jsonObject.put("deviceUnique", propertyEquipSaveDTO.getDeviceUnique());
        jsonObject.put("sn", sn);
        List<DeviceBusinessChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
        deviceBusinessChangeLogPOS.add(new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_DEVICE_ONE, jsonObject, projectId));

        saveVO.setUpdateCount(saveCloudIntercom);
        return deviceBusinessChangeLogPOS;
    }

    /**
     * <desc>
     *      提取添加设备License,QQ互联需要用到
     * <desc/>
     *
     * @param propertyEquipSaveDTO 物业设备保存DTO
     * @return DeviceCloudIntercomInfoPO 云对讲PO
     * @author Biao.R
     * @createDate 2017/10/30
     */
    private String addLicense(PropertyCloudIntercomSaveDTO propertyEquipSaveDTO) throws Exception {

        //添加设备的License
        String license = "";
        String sn = propertyEquipSaveDTO.getSn();
        String productTypeId = propertyEquipSaveDTO.getProductTypeId();
        String signSecretKey = propertyEquipSaveDTO.getSignSecretKey();
        String signPubKey = propertyEquipSaveDTO.getSignPubKey();

        String secKeyPath = String.format("%s%s", TENCENT_STATIC_FILE_PATH, PemFileUtil.getPemFileFullName(productTypeId, 1));
        String pubKeyPath = String.format("%s%s", TENCENT_STATIC_FILE_PATH, PemFileUtil.getPemFileFullName(productTypeId, 2));
        //LOG.info("-----secKeyPath:" + secKeyPath + "---pubKeyPath：" + pubKeyPath);
        TencentUtil tencentUtil = new TencentUtil();
        String licenseFilePath = tencentUtil.createAndCheckLicesnse(secKeyPath, pubKeyPath, sn, propertyEquipSaveDTO.getProjectId(), TENCENT_STATIC_FILE_PATH);
        license = tencentUtil.readLicenseFile(licenseFilePath);
        //LOG.info("设备签名：sn-" + sn + "-signSecretKey-" + signSecretKey + "-signPubKey-" + signPubKey + "-license-" + license);
        //LOG.info("License校验串:" + Md5.En(license));
        return license;
    }

    /**
     * <desc>
     *      给云对讲设备添加二维码
     * <desc/>
     *
     * @param deviceCloudIntercomInfoPO 云对讲PO
     * @return 生成二维码的存放地址
     * @author Biao.R
     * @createDate 2017/10/30
     */
    private String addQrCode(DeviceCloudIntercomInfoPO deviceCloudIntercomInfoPO) throws Exception {
        String pid = deviceCloudIntercomInfoPO.getProductTypeId();
        String sn = deviceCloudIntercomInfoPO.getSn();
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ByteArrayInputStream byteArrayInputStream = null;
        try {
            //添加生产二维码信息
            QrcodeUtils deviceQrCode = new QrcodeUtils();
            String imageType = "png";
            String content = PlatformConstants.CONSTANTS_EQUIP_CLOUDINTERCOM_QQ_IOT_URL + pid + "&sn=" + sn;

            //判断所需图片资源是否存在
            String weixinPath = String.format("%s%s", TENCENT_STATIC_FILE_PATH, "weixin.png");
            String qqLogoPath = String.format("%s%s", TENCENT_STATIC_FILE_PATH, "qqLogo.png");
            File weixinFile = new File(weixinPath);
            File qqLogoFile = new File(qqLogoPath);
            if (!weixinFile.exists() || !qqLogoFile.exists()) {
                throw new DataAccessException("【物业_设备服务】云对讲二维码静态资源获取失败");
            }
            //LOG.info("qqLogo路径：" + qqLogoPath + "--weixin路径：" + weixinPath);
            BufferedImage bim = deviceQrCode.getQR_CODEBufferedImage(content, BarcodeFormat.QR_CODE, 300, 300, deviceQrCode.getDecodeHintType());
            ImageIO.write(bim, "jpeg", weixinFile);
            BufferedImage bufferedImage = deviceQrCode.addLogo_QRCode(weixinFile, qqLogoFile, "", new LogoConfig());
            ImageIO.write(bufferedImage, "png", os);
            byteArrayInputStream = new ByteArrayInputStream(os.toByteArray());
            UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                    FILE_FTP_HOST,
                    FILE_FTP_USERNAME,
                    FILE_FTP_PASSWORD,
                    FILE_FTP_PORT,
                    byteArrayInputStream,
                    imageType,
                    FILE_ACCESS_URL,
                    FileCatalogEnum.DEVICEQRCODE_FILE.getType()
            );
            Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
            if ("true".equals(resultMap.get("returnCode").toString())) {
                return resultMap.get("accessPath").toString();
            } else {
                return null;
            }
        } catch (Exception ex) {
            throw new DataAccessException("【物业_设备服务】生成云对讲二维码失败", ex);
        } finally {
            os.close();
            if (byteArrayInputStream != null) {
                byteArrayInputStream.close();
            }
        }
    }

    /**
     * <desc>
     *      更新单个设备及其归属信息
     * <desc/>
     * @param   propertyEquipSaveDTO    物业设备数据转换对象
     * @return
     * @author zhangs
     * @createDate 2018/1/5
     */
    @Override
    public void updateEquip(PropertyCloudIntercomSaveDTO propertyEquipSaveDTO) throws Exception {

        String deviceUnique = propertyEquipSaveDTO.getDeviceUnique();
        Integer deviceType = Integer.parseInt(deviceUnique.substring(8, 9));
        propertyEquipSaveDTO.setDeviceId(null);
        //云对讲业务变更指令
        List<DeviceBusinessChangeLogPO> deviceBusinessChangeLogPOS = null;
        //云电梯业务变更指令
        List<DeviceBusinessElevatorChangeLogPO> deviceBusinessElevatorChangeLogPOs = null;
        //云门禁业务变更指令
        List<DeviceBusinessEntranceChangeLogPO> deviceBusinessEntranceChangeLogPOS = null;
        switch (PropertyEquipTypeEnum.getByEquipType(deviceType)) {
            case ELEVATOR:
                //更新电梯
                deviceBusinessElevatorChangeLogPOs=this.updateElevator(propertyEquipSaveDTO);
                break;
            case OUT_CALL_CONTROLLER:
                //更新电梯
                deviceBusinessElevatorChangeLogPOs=this.updateElevator(propertyEquipSaveDTO);
                break;
            case ENTRANCE:
                //更新门禁
                deviceBusinessEntranceChangeLogPOS =this.updateEntrance(propertyEquipSaveDTO);
                break;
            case CLOUD_INTERCOM:
                //更新云对讲
                deviceBusinessChangeLogPOS = this.updateCloudIntercom(propertyEquipSaveDTO);
                break;
            default:
                return;
        }
        if(propertyEquipSaveDTO.getElevatorType()== null || (propertyEquipSaveDTO.getElevatorType()!=null && propertyEquipSaveDTO.getElevatorType() != PropertyEquipTypeEnum.BLUETOOTH_CALL.getType())) {
            //设备地址变更，存储变更后的地址信息，等待定时任务刷新权限
            TimeTaskAuthDeviceAddressInfoPO deviceAddrPO = propertyEquipSaveDTO.getTimeTaskAuthDeviceAddressInfoPO();
            if (deviceAddrPO != null) {
                iTimeTaskAuthDeviceAddressInfoDao.save(SqlUtil.durableData(deviceAddrPO, PlatformConstants.TABLE_SAVE));
                if ((deviceType == PropertyEquipTypeEnum.ELEVATOR.getType() || deviceType == PropertyEquipTypeEnum.ENTRANCE.getType()) && iSmartCardFaceDao.isStartFaceByProjectId(propertyEquipSaveDTO.getProjectId()) > 0) {
                    String[] unit = StringHandlerUtil.splitString(deviceAddrPO.getUnitId());
                    List<String> userIdList = iDeviceAddressUserInfoServiceDao.getUserInfosByUnits(unit, propertyEquipSaveDTO.getProjectId());
                    if (userIdList != null) {
                        //发送C#人脸识别用户权限变更增量推送指令,先进行持久化，再由定时任务统一去处理 只有设备禁用启用时deviceUnique才不为空
                        SmartCardFaceTimePullInfoPO timePullInfoPO = new SmartCardFaceTimePullInfoPO();
                        timePullInfoPO.setPullId(LogicIdUtil.bussinessId());
                        timePullInfoPO.setProjectId(propertyEquipSaveDTO.getProjectId());
                        timePullInfoPO.setDeviceUniqueInfo("");
                        timePullInfoPO.setSyncStatus(1);
                        timePullInfoPO.setUserIdInfo(Joiner.on(",").join(userIdList));
                        timePullInfoPO.setStatus(1);
                        //由于权限更新需要一分钟，故此处为了保证权限最新故90秒后再进行定时任务下发增量数据
                        timePullInfoPO.setAllowSyncTime(DateUtil.addSecond(new Date(), 310));
                        timePullInfoPO.setCreateTime(new Date());
                        iSmartCardFaceDao.save(SqlUtil.durableData(timePullInfoPO, PlatformConstants.TABLE_SAVE));
                    }
                }
            } else {
                //如果设备名称发生变化，通知App刷新用户权限缓存
                if (propertyEquipSaveDTO.getIsOnlyNameChange()) {
                    //物业APP清除缓存
                    redisService.del(RedisConstant.REDIS_PROPERTY_APP_USER_DEVICE_CACHE + propertyEquipSaveDTO.getLoginUserId() + propertyEquipSaveDTO.getProjectId());
                    //通过设备查询拥有该设备权限的userId
                    List<String> userIdList = ipropertyDeviceAuthService.getAuthUserIdByDeviceUnique(deviceUnique);
                    if (userIdList != null && !userIdList.isEmpty()) {
                        Map<String, Object> param = new HashMap<>();
                        param.put("projectId", propertyEquipSaveDTO.getProjectId());
                        for (String userId : userIdList) {
                            param.put("userId", userId);
                            try {
                                messageSender.send(RabbitMQConstant.RABBITMQ_EQUIP_APP_USER_INFO_DEVICE_UPDATE_QUEUE,
                                        JSON.toJSONString(param), RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                                        RabbitMQConstant.RABBITMQ_EQUIP_APP_USER_INFO_DEVICE_UPDATE_KEY);
                            } catch (Exception e) {
                                throw new DataAccessException("【更新设备】更新设备名称异常:", e);
                            }
                        }
                    }
                }
            }
            // 推送云对讲重启指令
            if (deviceBusinessChangeLogPOS != null && !deviceBusinessChangeLogPOS.isEmpty()) {
                this.pushCloudIntercom(deviceBusinessChangeLogPOS);
            }
            //推送云电梯重启指令
            if (deviceBusinessElevatorChangeLogPOs != null && !deviceBusinessElevatorChangeLogPOs.isEmpty()) {
                this.pushElevator(deviceBusinessElevatorChangeLogPOs);
            }
            //推送云门禁重启指令
            if (deviceBusinessEntranceChangeLogPOS != null && !deviceBusinessEntranceChangeLogPOS.isEmpty()) {
                this.pushEntrance(deviceBusinessEntranceChangeLogPOS);
            }
        }
    }

    /**
     * <desc>
     *      添加单个电梯及其归属信息
     * <desc/>
     *
     * @param propertyEquipSaveDTO 物业设备数据传输对象
     * @return 设备更新返回数据VO
     * @author Biao.R
     * @createDate 2017/9/26
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<DeviceBusinessElevatorChangeLogPO> updateElevator(PropertyCloudIntercomSaveDTO propertyEquipSaveDTO) throws Exception {

        //查询电梯是否为线下平台所添加（普通电梯及无地址），并且是否要改为云电梯及临时升级表是否有该条数据，若有则删除
        //Integer mark = iPropertyEquipDao.getElevatorInfo(propertyEquipSaveDTO.getDeviceUnique());
        if(propertyEquipSaveDTO.getElevatorType()==PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType()){
            if(iPropertyEquipDao.isExistInSpecialElevator(propertyEquipSaveDTO.getDeviceUnique())>0){
                iPropertyEquipDao.deleteSpecialElevatorByDeviceUnique(propertyEquipSaveDTO.getDeviceUnique());
            }
        }

        //处理群控器下所有电梯的公共楼层，需保持一致
        String controllerDeviceUnique = iDeviceCloudControllerDao.getControllerByElevator(propertyEquipSaveDTO.getDeviceUnique());
        //电梯被群控器所绑定，则需要处理其公共楼层
        if(StringUtils.isNotEmpty(controllerDeviceUnique)){
            iDeviceCloudControllerDao.updateCommonFloorByElevator(StringUtils.isEmpty(propertyEquipSaveDTO.getCommonFloor())?"":propertyEquipSaveDTO.getCommonFloor(),controllerDeviceUnique);
        }
        PropertyEquipUpdateVO updateVO = new PropertyEquipUpdateVO();
        //添加电梯信息表
        Date currentTime = new Date();
        DeviceElevatorInfoPO deviceElevatorInfoPO = new DeviceElevatorInfoPO();
        BeanUtils.copyProperties(propertyEquipSaveDTO, deviceElevatorInfoPO);
        Integer status = propertyEquipSaveDTO.getStatus();
        deviceElevatorInfoPO.setStatus(status == null ? DataStatusEnum.NORMAL.getType() : status);
        deviceElevatorInfoPO.setIotProductId(iPropertyEquipDao.getIotProductId(1,propertyEquipSaveDTO.getProjectId()));
        Integer elevatorType = propertyEquipSaveDTO.getElevatorType();
        deviceElevatorInfoPO.setElevatorType(elevatorType);
        //此处判断所添加的设备是云电梯的情况
        if(elevatorType == PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType()){
            deviceElevatorInfoPO.setElevatorType(elevatorType);
            deviceElevatorInfoPO.setCommonFloor(propertyEquipSaveDTO.getCommonFloor());
            deviceElevatorInfoPO.setIsBluetoothElevator(propertyEquipSaveDTO.getIsBluetoothElevator());
            deviceElevatorInfoPO.setToken(propertyEquipSaveDTO.getToken());
        }
        if(elevatorType == PropertyEquipTypeEnum.BLUETOOTH_ELEVATOR.getType()){
            deviceElevatorInfoPO.setElevatorType(elevatorType);
        }

        String deviceUnique = deviceElevatorInfoPO.getDeviceUnique();
        Integer floorNo = deviceElevatorInfoPO.getFloorNo();
        String projectId = propertyEquipSaveDTO.getProjectId();
        TimeTaskAuthDeviceAddressInfoPO deviceAddrPO = propertyEquipSaveDTO.getTimeTaskAuthDeviceAddressInfoPO();
        deviceElevatorInfoPO.setUpdateTime(currentTime);

        //查询旧的设备
        DeviceElevatorInfoPO oldElevator = iPropertyElevatorDao.getByDeviceUnique(deviceUnique);
        if (StringUtils.isEmpty(oldElevator.getOpenThreshold())) {
            deviceElevatorInfoPO.setOpenThreshold(PlatformConstants.EQUIP_BLUETOOTH_OPEN_THRESHOLD);
        }

        deviceElevatorInfoPO.setProjectId(null);
        //对比更新前后的地址
        boolean updateAddr =false;
        List<EquipAddressGetVO> oldAddresss = iDeviceElevatorBridgeInfoDao.getAddress(deviceUnique);
        List<String> delIdList = new ArrayList<>();
        if (oldAddresss != null && oldAddresss.size() > 0) {
            for (EquipAddressGetVO deviceElevatorBridgeInfoPO : oldAddresss) {
                delIdList.add(deviceElevatorBridgeInfoPO.getId().toString());
            }
            int size = oldAddresss.size();
            String unitId = oldAddresss.get(0).getUnitId();
            if (size == 1 && StringUtils.isEmpty(unitId)) {
                updateAddr = true;
            }
        }
        List<DeviceBusinessElevatorChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
        //如果设备归属地发生变化，删除原来的，插入新添加的
        if (deviceAddrPO != null || updateAddr) {
            if(elevatorType != PropertyEquipTypeEnum.BLUETOOTH_CALL.getType()) {
                this.addElevatorFloor(deviceElevatorInfoPO);
                deviceElevatorInfoPO.setFloorNo(1);
                deviceElevatorInfoPO.setFloorNoMax(propertyEquipSaveDTO.getFloorNoMax() < 0 && propertyEquipSaveDTO.getFloorNoMax() == -1 ?
                                Math.abs(propertyEquipSaveDTO.getFloorNo()) :
                                propertyEquipSaveDTO.getFloorNoMax() < 0 && propertyEquipSaveDTO.getFloorNoMax() != -1 ?
                                        Math.abs(propertyEquipSaveDTO.getFloorNo()) - Math.abs(propertyEquipSaveDTO.getFloorNo() + 1) :
                                        propertyEquipSaveDTO.getFloorNo() < 0 ?
                                                Math.abs(propertyEquipSaveDTO.getFloorNo()) + propertyEquipSaveDTO.getFloorNoMax() :
                                                propertyEquipSaveDTO.getFloorNo() == 1 ? propertyEquipSaveDTO.getFloorNoMax() :
                                                        propertyEquipSaveDTO.getFloorNoMax() - propertyEquipSaveDTO.getFloorNo() + 1
                );
            }
            //添加电梯归属信息表
            String unitIds = propertyEquipSaveDTO.getUnitIds();
            String buildIds = propertyEquipSaveDTO.getBuildIds();
            List<Map<String, Object>> saveDeviceElevatorBridgeInfoPOList = new ArrayList<>();

            if (null != buildIds && null != unitIds) {
                String[] unitIdArr = unitIds.split(",");
                for (String unitId : unitIdArr) {
                    DeviceElevatorBridgeInfoPO deviceElevatorBridgeInfoPO = new DeviceElevatorBridgeInfoPO(deviceUnique, projectId, buildIds, unitId);
                    deviceElevatorBridgeInfoPO.setCreateTime(currentTime);
                    Map<String, Object> map = SqlUtil.durableData(deviceElevatorBridgeInfoPO, PlatformConstants.TABLE_SAVE);
                    saveDeviceElevatorBridgeInfoPOList.add(map);
                }
            }

            if (saveDeviceElevatorBridgeInfoPOList.size() > 0) {
                iDeviceElevatorBridgeInfoDao.batchSave(saveDeviceElevatorBridgeInfoPOList);
            }
            if (delIdList.size() > 0) {
                iDeviceElevatorBridgeInfoDao.batchDelEleById(delIdList);
            }
            JSONArray jsonArrayCloudElevator = new JSONArray();
            JSONObject jsonObject=new JSONObject();
            jsonObject.put("sn",oldElevator.getSn());
            jsonObject.put("deviceUnique",oldElevator.getDeviceUnique());
            jsonObject.put("projectId",projectId);
            jsonArrayCloudElevator.add(jsonObject);
            deviceBusinessChangeLogPOS.add(new DeviceBusinessElevatorChangeLogPO(projectId,CloudElevatorChangeBusinessEnum.PUSH_DEVICE_INFO,jsonArrayCloudElevator.toJSONString()));
        }else{
            deviceElevatorInfoPO.setFloorNo(null);
            deviceElevatorInfoPO.setFloorNoMax(null);
        }
//        this.addElevatorFloor(deviceElevatorInfoPO);
//        deviceElevatorInfoPO.setFloorNo(1);
//        deviceElevatorInfoPO.setFloorNoMax(propertyEquipSaveDTO.getFloorNoMax() < 0 && propertyEquipSaveDTO.getFloorNoMax() == -1 ?
//                        Math.abs(propertyEquipSaveDTO.getFloorNo()) :
//                        propertyEquipSaveDTO.getFloorNoMax() < 0 && propertyEquipSaveDTO.getFloorNoMax() != -1 ?
//                                Math.abs(propertyEquipSaveDTO.getFloorNo()) - Math.abs(propertyEquipSaveDTO.getFloorNo() +1)  :
//                                propertyEquipSaveDTO.getFloorNo() < 0 ?
//                                        Math.abs(propertyEquipSaveDTO.getFloorNo()) + propertyEquipSaveDTO.getFloorNoMax() :
//                                        propertyEquipSaveDTO.getFloorNo() == 1 ? propertyEquipSaveDTO.getFloorNoMax() :
//                                                propertyEquipSaveDTO.getFloorNoMax()-propertyEquipSaveDTO.getFloorNo()+1
//        );
//        deviceElevatorInfoPO.setFloorNo(null);
//        deviceElevatorInfoPO.setFloorNoMax(null);
        if(propertyEquipSaveDTO.getFloorNums()!=null) {
            deviceElevatorInfoPO.setFloorNum(Integer.valueOf(propertyEquipSaveDTO.getFloorNums()));
        }
        Integer updateElevator = iPropertyElevatorDao.update(SqlUtil.durableData(deviceElevatorInfoPO, PlatformConstants.TABLE_UPDATE));
        //推送数据给一卡通
        List<DeviceElevatorInfoPO> deviceInfoPOS = new ArrayList();
        deviceInfoPOS.add(deviceElevatorInfoPO);
        //发送数据
        prepareEquipInfoForSyncToSmartCard(projectId, JSON.toJSONString(deviceInfoPOS), SmartCardSyncDataOperTypeEnum.UPDATE);

        updateVO.setUpdateCount(updateElevator);

        //对比设备名称是否有改变
        if((elevatorType == PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType() &&
                !oldElevator.getDeviceName().equals(propertyEquipSaveDTO.getDeviceName()))
                ||oldElevator.getEquipMode()!=propertyEquipSaveDTO.getEquipMode()){
            JSONObject jsonObject=new JSONObject();
            jsonObject.put("sn",oldElevator.getSn());
            jsonObject.put("deviceUnique",oldElevator.getDeviceUnique());
            jsonObject.put("projectId",projectId);
            DeviceBusinessElevatorChangeLogPO deviceBusinessChangeLogPO = new DeviceBusinessElevatorChangeLogPO(projectId,CloudElevatorChangeBusinessEnum.PUSH_DEVICE_PROJECT,jsonObject.toJSONString());
            deviceBusinessChangeLogPOS.add(deviceBusinessChangeLogPO);
        }
        Map<String,Object> map = SqlUtil.durableData(deviceElevatorInfoPO, PlatformConstants.TABLE_UPDATE);
        String changeDeviceUnique = null;
        if(elevatorType==13 && StringHandlerUtil.getDeviceTypeByDeviceUnique(deviceElevatorInfoPO.getDeviceUnique()) != 4){
            changeDeviceUnique = StringHandlerUtil.getProjectIdByDeviceUnique(deviceElevatorInfoPO.getDeviceUnique())+"4"+StringHandlerUtil.getDeviceIdByDeviceUnique(deviceElevatorInfoPO.getDeviceUnique());
        }else if(elevatorType!=13 && StringHandlerUtil.getDeviceTypeByDeviceUnique(deviceElevatorInfoPO.getDeviceUnique()) == 4){
            changeDeviceUnique = StringHandlerUtil.getProjectIdByDeviceUnique(deviceElevatorInfoPO.getDeviceUnique())+"4"+StringHandlerUtil.getDeviceIdByDeviceUnique(deviceElevatorInfoPO.getDeviceUnique());
        }
        map.put("changeDeviceUnique",changeDeviceUnique);
        if (PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType().equals(elevatorType) && !oldElevator.getEquipMode().equals(propertyEquipSaveDTO.getEquipMode())) {
            JSONObject jsonObject=new JSONObject();
            jsonObject.put("sn",oldElevator.getSn());
            jsonObject.put("deviceUnique",oldElevator.getDeviceUnique());
            jsonObject.put("projectId",projectId);
            DeviceBusinessElevatorChangeLogPO deviceBusinessChangeLogPO = new DeviceBusinessElevatorChangeLogPO(projectId,CloudElevatorChangeBusinessEnum.PUSH_DEVICE_PROJECT,jsonObject.toJSONString());
            deviceBusinessChangeLogPOS.add(deviceBusinessChangeLogPO);
        }
        //对比电梯的起始楼层是否有改变，如有则发送消息队列
//        if(oldElevator.getFloorNo()!=propertyEquipSaveDTO.getFloorNo() || oldElevator.getFloorNoMax()!=propertyEquipSaveDTO.getFloorNoMax()){
//            Map<String, Object> map = new HashMap<>();
//            ElevatorFloorChangeDTO floorChangeDTO = new ElevatorFloorChangeDTO();
//            floorChangeDTO.setDeviceUnique(deviceUnique);
//            floorChangeDTO.setProjectId(projectId);
//            floorChangeDTO.setOldStartFloor(oldElevator.getFloorNo());
//            floorChangeDTO.setOldEndFloor(oldElevator.getFloorNoMax());
//            floorChangeDTO.setNewStartFloor(propertyEquipSaveDTO.getFloorNo());
//            floorChangeDTO.setNewEndFloor(propertyEquipSaveDTO.getFloorNoMax());
//            map.put("elevator", floorChangeDTO);
//            messageSender.send(
//                    RabbitMQConstant.RABBITMQ_CHANGE_USER_ELEVATOR_FLOOR_AUTH_QUEUE,
//                    JSON.toJSONString(map),
//                    RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
//                    RabbitMQConstant.RABBITMQ_CHANGE_USER_ELEVATOR_FLOOR_AUTH_KEY
//            );
//        }
        if(elevatorType == PropertyEquipTypeEnum.BLUETOOTH_CALL.getType()){
            //清空已绑定数据
            iPropertyEquipDao.deleteBluetoothCallRelation(deviceElevatorInfoPO.getDeviceUnique());
            //蓝牙外呼设备
            if(StringUtils.isNotBlank(propertyEquipSaveDTO.getElevatorDeviceUniques())){
                String[] elevators = StringHandlerUtil.splitString(propertyEquipSaveDTO.getElevatorDeviceUniques());
                for(String elevator : elevators){
                    BluetoothCallElevatorRelationPO call = new BluetoothCallElevatorRelationPO();
                    call.setElevatorDeviceUnique(elevator);
                    call.setDeviceUnique(deviceElevatorInfoPO.getDeviceUnique());
                    call.setRelationId(LogicIdUtil.bussinessId());
                    call.setNaturalFloor(iPropertyEquipDao.getNaturalFloorByFloorNum(propertyEquipSaveDTO.getFloorNums().toString(), call.getElevatorDeviceUnique()));
                    call.setCreateTime(new Date());
                    call.setUpdateTime(new Date());
                    iPropertyEquipDao.save(SqlUtil.durableData(call,PlatformConstants.TABLE_SAVE));
                }
            }
        }

        return deviceBusinessChangeLogPOS;
    }


    /**
     * <desc>
     *      更新单个门禁及其归属信息
     * <desc/>
     *
     * @param propertyEquipSaveDTO 物业设备数据传输对象
     * @return 设备更新返回数据VO
     * @author Biao.R
     * @createDate 2017/9/26
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<DeviceBusinessEntranceChangeLogPO> updateEntrance(PropertyCloudIntercomSaveDTO propertyEquipSaveDTO) throws Exception {

        //查询门禁是否为线下平台所添加（蓝牙门禁、无地址及无绑定电梯），并且是否要改为云门禁、云联动器及临时升级表是否有该条数据，若有则删除
        //Integer mark = iPropertyEquipDao.getEntranceInfo(propertyEquipSaveDTO.getDeviceUnique());
        if(propertyEquipSaveDTO.getEntranceCategory()==PropertyEquipTypeEnum.CLOUD_ENTRANCE_DEVICE.getType()
                || propertyEquipSaveDTO.getEntranceCategory()==PropertyEquipTypeEnum.CLOUD_WIPPEN_DEVICE.getType()
                || propertyEquipSaveDTO.getEntranceCategory()==PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType()){
            if(iPropertyEquipDao.isExistInSpecialEntrance(propertyEquipSaveDTO.getDeviceUnique())>0){
                iPropertyEquipDao.deleteSpecialEntranceByDeviceUnique(propertyEquipSaveDTO.getDeviceUnique());
            }
        }

        List<DeviceBusinessEntranceChangeLogPO> deviceBusinessEntranceChangeLogPOS = new ArrayList<>();
        PropertyEquipUpdateVO updateVO = new PropertyEquipUpdateVO();
        //更新门禁信息表
        Date currentTime = new Date();
        DeviceEntranceInfoPO deviceEntranceInfoPO = new DeviceEntranceInfoPO();
        BeanUtils.copyProperties(propertyEquipSaveDTO, deviceEntranceInfoPO);
        deviceEntranceInfoPO.setIotProductId(iPropertyEquipDao.getIotProductId(2,propertyEquipSaveDTO.getProjectId()));
        Integer status = propertyEquipSaveDTO.getStatus();
        deviceEntranceInfoPO.setStatus(status == null ? DataStatusEnum.NORMAL.getType() : status);
        String deviceUnique = deviceEntranceInfoPO.getDeviceUnique();
        String projectId = propertyEquipSaveDTO.getProjectId();
        TimeTaskAuthDeviceAddressInfoPO deviceAddrPO = propertyEquipSaveDTO.getTimeTaskAuthDeviceAddressInfoPO();
        deviceEntranceInfoPO.setUpdateTime(currentTime);
        deviceEntranceInfoPO.setElevatorDeviceUnique(propertyEquipSaveDTO.getElevatorDeviceUnique());
        deviceEntranceInfoPO.setElevatorFloor(propertyEquipSaveDTO.getElevatorFloor());
        //查询旧的设备
        DeviceEntranceInfoPO oldEntrance = iDeviceEntranceInfoDao.getByDeviceUnique(deviceUnique);
        if (StringUtils.isEmpty(oldEntrance.getOpenThreshold())) {
            deviceEntranceInfoPO.setOpenThreshold(PlatformConstants.EQUIP_BLUETOOTH_OPEN_THRESHOLD);
        }
        //此处处理当蓝牙门禁变成云门禁时需清除 蓝牙门禁与电梯间的关系 解决APP列表查询不到设备问题
        if(oldEntrance.getEntranceCategory()==PropertyEquipTypeEnum.BLUETOOTH_ENTRANCE.getType() &&
                propertyEquipSaveDTO.getEntranceCategory() != PropertyEquipTypeEnum.BLUETOOTH_ENTRANCE.getType()){
            deviceEntranceInfoPO.setElevatorDeviceUnique(null);
            deviceEntranceInfoPO.setElevatorFloor(null);
        }

        if((PropertyEquipTypeEnum.CLOUD_ENTRANCE_DEVICE.getType()==propertyEquipSaveDTO.getEntranceCategory()
                || PropertyEquipTypeEnum.CLOUD_WIPPEN_DEVICE.getType()==propertyEquipSaveDTO.getEntranceCategory()
                || PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType()==propertyEquipSaveDTO.getEntranceCategory()
                || PropertyEquipTypeEnum.CLOUD_UNIBODY_ENTRANCE_DEVICE.getType()==propertyEquipSaveDTO.getEntranceCategory())
                && PropertyEquipTypeEnum.BLUETOOTH_ENTRANCE.getType()==oldEntrance.getEntranceCategory()){
            deviceEntranceInfoPO.setBindDeviceGroup(propertyEquipSaveDTO.getSn());
        }

        // 普通门禁变成其它门禁时，住户角色组若绑定了该门禁，则要清除关系
        importAddressFixedThreadPool.execute(() -> {
            DeviceEntranceInfoPO byDeviceUnique = iDeviceEntranceInfoDao.getByDeviceUnique(deviceEntranceInfoPO.getDeviceUnique());
            if (byDeviceUnique != null &&  new Integer(3).equals(byDeviceUnique.getEntranceType()) &&  !new Integer(3).equals(deviceEntranceInfoPO.getEntranceType())) {
                try {
                    // 拿到当前项目所有普通门禁设备序列号字符串
                    String currentDevices = iDeviceEntranceInfoDao.getAllDeviceUniqueStr(projectId);
                    if (StringUtils.isBlank(currentDevices)) {
                        currentDevices = "";
                    }
                    // 拿到该设备序列号被绑定的所有roleId
                    List<String> roleIdList = iDeviceEntranceInfoDao.getRoleIdsByDeviceUnique(deviceEntranceInfoPO.getDeviceUnique());
                    if (roleIdList != null && !roleIdList.isEmpty()) {
                        for (String roleId : roleIdList) {
                            // 拿到角色绑定的用户id列表
                            List<String> userIdListByRoleId = iDeviceEntranceInfoDao.getUserIdListByRoleId(roleId);
                            if (userIdListByRoleId == null || userIdListByRoleId.isEmpty()) {
                                continue;
                            }
                            // 拿到角色绑定的设备序列号列表
                            List<String> deviceUniqueListByRoleId = iDeviceEntranceInfoDao.getDeviceUniqueListByRoleId(roleId);
                            if (deviceUniqueListByRoleId == null || deviceUniqueListByRoleId.isEmpty()) {
                                continue;
                            }
                            // 去掉这个序列号
                            deviceUniqueListByRoleId.remove(deviceEntranceInfoPO.getDeviceUnique());
                            String deviceUniqueStrByRoleId = deviceUniqueListByRoleId.toString().replace("[", "").replace("]", "").replaceAll(" ","");
                            for (String userId : userIdListByRoleId) {
                                ipropertyDeviceAuthService.updateHouseHoldTmpDeviceAuth(propertyEquipSaveDTO.getLoginUserId(),userId,projectId,2,currentDevices,deviceUniqueStrByRoleId,
                                        new ArrayList<>(),"mark");
                            }
                        }
                    }
                } catch (Exception e) {
                    LOG.error("修改门禁时清除普通门禁和角色组绑定的住户关系时异常", e);
                }
                iDeviceEntranceInfoDao.deleteDeviceEntranceRole(deviceEntranceInfoPO.getDeviceUnique());
            }
        });
        if(StringUtils.isNotEmpty(propertyEquipSaveDTO.getSupportFunction()) && propertyEquipSaveDTO.getSupportFunction().contains("6")){
            deviceEntranceInfoPO.setIsFaceRecognition(1);
        }
        Integer updateEntrance = iDeviceEntranceInfoDao.update(SqlUtil.durableData(deviceEntranceInfoPO, PlatformConstants.TABLE_UPDATE));

        List<DeviceEntranceBridgeInfoPO> oldAddresss = iDeviceEntranceBridgeInfoDao.getAddress(propertyEquipSaveDTO.getDeviceUnique());
        List<String> delIdList = new ArrayList<>();
        boolean updateAddr = false;
        if (oldAddresss != null && oldAddresss.size() > 0) {
            for (DeviceEntranceBridgeInfoPO deviceEntranceBridgeInfoPO : oldAddresss) {
                delIdList.add(deviceEntranceBridgeInfoPO.getId().toString());
            }
            int size = oldAddresss.size();
            String unitId = oldAddresss.get(0).getUnitId();
            if (size == 1 && StringUtils.isEmpty(unitId)) {
                updateAddr = true;
            }
        }
        //前后对比归属地地址不同
        if (deviceAddrPO != null  || updateAddr) {
            //如果所修改门禁由单元楼栋门禁为普通门禁时则直接将之前门禁归属信息删除即可
            if(propertyEquipSaveDTO.getEntranceType() != EntranceTypeEnum.COMMON_ENTRANCE.getType()){
                //更新门禁归属信息表
                String unitIds = propertyEquipSaveDTO.getUnitIds();
                String buildIds = propertyEquipSaveDTO.getBuildIds();
                List<Map<String, Object>> saveEntranceAddrList = new ArrayList<>();
                if (StringUtils.isNotEmpty(unitIds) || buildIds.split(",").length == 1) {
                    if (StringUtils.isBlank(unitIds)) {
                        unitIds = iDeviceEntranceBridgeInfoDao.getUnitsByBuild(buildIds);
                    }
                    String[] unitIdArr = unitIds.split(",");
                    //门禁归属于一栋多单元
                    for (String unitId : unitIdArr) {
                        DeviceEntranceBridgeInfoPO deviceEntranceBridgeInfoPO = new DeviceEntranceBridgeInfoPO(deviceEntranceInfoPO.getDeviceUnique(), projectId, buildIds, unitId);
                        deviceEntranceBridgeInfoPO.setCreateTime(currentTime);
                        Map<String, Object> map = SqlUtil.durableData(deviceEntranceBridgeInfoPO, PlatformConstants.TABLE_SAVE);
                        saveEntranceAddrList.add(map);
                    }
                } else {
                    //门禁归属于多栋
                    String[] buildIdArr = buildIds.split(",");
                    for (String buildId : buildIdArr) {
                        DeviceEntranceBridgeInfoPO deviceEntranceBridgeInfoPO = new DeviceEntranceBridgeInfoPO(deviceEntranceInfoPO.getDeviceUnique(), projectId, buildId, null);
                        deviceEntranceBridgeInfoPO.setCreateTime(currentTime);
                        Map<String, Object> map = SqlUtil.durableData(deviceEntranceBridgeInfoPO, PlatformConstants.TABLE_SAVE);
                        saveEntranceAddrList.add(map);
                    }
                }

                if (!saveEntranceAddrList.isEmpty()) {
                    iDeviceEntranceBridgeInfoDao.batchSave(saveEntranceAddrList);
                }
            }

            if (!delIdList.isEmpty()) {
                iDeviceEntranceBridgeInfoDao.batchDeleteById(delIdList);
            }
            if((propertyEquipSaveDTO.getEntranceCategory() == PropertyEquipTypeEnum.CLOUD_ENTRANCE_DEVICE.getType() ||
                    propertyEquipSaveDTO.getEntranceCategory() == PropertyEquipTypeEnum.CLOUD_WIPPEN_DEVICE.getType() ||
                    propertyEquipSaveDTO.getEntranceCategory() == PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType() ||
                    propertyEquipSaveDTO.getEntranceCategory() == PropertyEquipTypeEnum.CLOUD_UNIBODY_ENTRANCE_DEVICE.getType()
            )){
                // 地址变化，推送云对讲重启指令
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("deviceUnique", deviceUnique);
                jsonObject.put("projectId", projectId);
                jsonObject.put("sn", oldEntrance.getSn());
                deviceBusinessEntranceChangeLogPOS.add(new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_DEVICE_ONE, jsonObject, projectId));
            }
        }

        //设备名称发生变化时，推送设备云对讲拉取基础信息指令
        if (!(oldEntrance.getDeviceName()).equals(deviceEntranceInfoPO.getDeviceName())
                && (propertyEquipSaveDTO.getEntranceCategory() == PropertyEquipTypeEnum.CLOUD_ENTRANCE_DEVICE.getType() ||
                propertyEquipSaveDTO.getEntranceCategory() == PropertyEquipTypeEnum.CLOUD_WIPPEN_DEVICE.getType() ||
                propertyEquipSaveDTO.getEntranceCategory() == PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType() ||
                propertyEquipSaveDTO.getEntranceCategory() == PropertyEquipTypeEnum.CLOUD_UNIBODY_ENTRANCE_DEVICE.getType())
                && deviceBusinessEntranceChangeLogPOS.isEmpty()) {
            JSONArray jsonArray = new JSONArray();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("deviceUnique", deviceUnique);
            jsonArray.add(jsonObject);
            deviceBusinessEntranceChangeLogPOS.add(new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_DEVICE,jsonArray,projectId));
        }
        //设备名称发生变化时，推送设备云对讲拉取基础信息指令
        if (!(oldEntrance.getEquipMode()).equals(deviceEntranceInfoPO.getEquipMode())
                && (PropertyEquipTypeEnum.CLOUD_ENTRANCE_DEVICE.getType().equals(propertyEquipSaveDTO.getEntranceCategory()) ||
                PropertyEquipTypeEnum.CLOUD_WIPPEN_DEVICE.getType().equals(propertyEquipSaveDTO.getEntranceCategory()) ||
                PropertyEquipTypeEnum.CLOUD_UNIBODY_FACE_DEVICE.getType()==propertyEquipSaveDTO.getEntranceCategory() ||
                propertyEquipSaveDTO.getEntranceCategory() == PropertyEquipTypeEnum.CLOUD_UNIBODY_ENTRANCE_DEVICE.getType())
                && deviceBusinessEntranceChangeLogPOS.isEmpty()) {
            JSONArray jsonArray = new JSONArray();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("deviceUnique", deviceUnique);
            jsonArray.add(jsonObject);
            deviceBusinessEntranceChangeLogPOS.add(new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_DEVICE,jsonArray,projectId));
        }

        iDeviceEntranceBridgeInfoDao.deleteByDeviceUnique(propertyEquipSaveDTO.getDeviceUnique());
        //保存该门禁所支持功能类型信息
        if(StringUtils.isNotEmpty(propertyEquipSaveDTO.getSupportFunction())){
            String[] strArr = propertyEquipSaveDTO.getSupportFunction().split(",");
            if(strArr!=null){
                List<Map<String, Object>> saveEntranceFunctionList = new ArrayList<>();
                for(String str : strArr){
                    DeviceEntranceFunctionInfoPO deviceEntranceFunctionInfo = new DeviceEntranceFunctionInfoPO();
                    deviceEntranceFunctionInfo.setDeviceUnique(propertyEquipSaveDTO.getDeviceUnique());
                    deviceEntranceFunctionInfo.setFunctionType(Integer.parseInt(str));
                    deviceEntranceFunctionInfo.setFunctionTypeName(EntranceFunctionEnum.getDescription(Integer.parseInt(str)));
                    deviceEntranceFunctionInfo.setStatus(DataStatusEnum.NORMAL.getType());
                    deviceEntranceFunctionInfo.setCreateTime(new Date());
                    deviceEntranceFunctionInfo.setUpdateTime(new Date());
                    saveEntranceFunctionList.add(SqlUtil.durableData(deviceEntranceFunctionInfo,PlatformConstants.TABLE_SAVE));
                }
                if(!saveEntranceFunctionList.isEmpty()){
                    iDeviceEntranceBridgeInfoDao.batchSaveFunction(saveEntranceFunctionList);
                }
            }
        }

        //推送数据给一卡通
        List<DeviceEntranceInfoPO> deviceInfoPOS = new ArrayList();
        deviceInfoPOS.add(deviceEntranceInfoPO);
        //发送数据
        prepareEquipInfoForSyncToSmartCard(projectId, JSON.toJSONString(deviceInfoPOS), SmartCardSyncDataOperTypeEnum.UPDATE);

        updateVO.setUpdateCount(updateEntrance);

        return deviceBusinessEntranceChangeLogPOS;
    }


    /**
     * <desc>
     *      更新单个云对讲及其归属信息
     * <desc/>
     *
     * @param propertyEquipSaveDTO 物业设备数据传输对象
     * @return  设备更新返回数据VO
     * @author Biao.R
     * @createDate 2017/9/26
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public List<DeviceBusinessChangeLogPO> updateCloudIntercom(PropertyCloudIntercomSaveDTO propertyEquipSaveDTO) throws Exception {

        //更新云对讲信息表
        PropertyEquipUpdateVO updateVO = new PropertyEquipUpdateVO();
        Date currentTime = new Date();
        DeviceCloudIntercomInfoPO deviceCloudIntercomInfoPO = new DeviceCloudIntercomInfoPO();
        BeanUtils.copyProperties(propertyEquipSaveDTO, deviceCloudIntercomInfoPO);
        Integer status = propertyEquipSaveDTO.getStatus();
        deviceCloudIntercomInfoPO.setStatus(status == null ? DataStatusEnum.NORMAL.getType() : status);
        String projectId = propertyEquipSaveDTO.getProjectId();
        TimeTaskAuthDeviceAddressInfoPO deviceAddrPO = propertyEquipSaveDTO.getTimeTaskAuthDeviceAddressInfoPO();
        String sn = deviceCloudIntercomInfoPO.getSn();
        deviceCloudIntercomInfoPO.setUpdateTime(currentTime);

        String deviceUnique = deviceCloudIntercomInfoPO.getDeviceUnique();
        DeviceCloudIntercomInfoPO oldCloudIntercom = iDeviceCloudIntercomInfoDao.getByDeviceUnique(deviceUnique, null);
        String oldSn = "";
        if (oldCloudIntercom != null) {
            oldSn = oldCloudIntercom.getSn();
        }

        deviceCloudIntercomInfoPO.setSn(sn);
        deviceCloudIntercomInfoPO.setSipAccount(DEVICE_SIP_ACCOUNT_PREFIX+sn);
        deviceCloudIntercomInfoPO.setSipPsd(sn);
        deviceCloudIntercomInfoPO.setStatus(DataStatusEnum.NORMAL.getType());

        /*//添加License
        String license = this.addLicense(propertyEquipSaveDTO);
        deviceCloudIntercomInfoPO.setLicense(license);
        deviceCloudIntercomInfoPO.setMd5(Md5.En(license));*/

        //添加二维码信息:相应数据变化时更新二维码
        /*String oldPid = oldCloudIntercom.getProductTypeId();
        String newPid = deviceCloudIntercomInfoPO.getProductTypeId();
        if (StringUtils.isEmpty(oldCloudIntercom.getQrCode()) || !oldSn.equals(sn) || !oldPid.equals(newPid)) {*/
//        if (StringUtils.isEmpty(oldCloudIntercom.getQrCode()) || !oldSn.equals(sn)) {
//            String qrCodeSavePath = this.addQrCode(deviceCloudIntercomInfoPO);
//            deviceCloudIntercomInfoPO.setQrCode(qrCodeSavePath);
//        }
        Integer saveCloudIntercom = iDeviceCloudIntercomInfoDao.update(SqlUtil.durableData(deviceCloudIntercomInfoPO, PlatformConstants.TABLE_UPDATE));

        boolean updateAddr = false;
        List<DeviceCloudIntercomBridgeInfoPO> oldAddresss = iDeviceCloudIntercomBridgeInfoDao.getAddress(deviceUnique);
        List<String> delIdList = new ArrayList<>();
        if (oldAddresss != null && !oldAddresss.isEmpty()) {
            for (DeviceCloudIntercomBridgeInfoPO deviceCloudIntercomBridgeInfo : oldAddresss) {
                delIdList.add(deviceCloudIntercomBridgeInfo.getId().toString());
            }
            int size = oldAddresss.size();
            String unitId = oldAddresss.get(0).getUnitId();
            if (size == 1 && StringUtils.isEmpty(unitId)) {
                updateAddr = true;
            }
        }
        List<DeviceBusinessChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();

        //sn账号发生变化 :更新sip信息,删除更新前的sip,并插入新的,还要推送两条云对讲指令
        boolean isSnChange = StringUtils.isNotBlank(oldSn) && !oldSn.equals(sn);
        if (isSnChange) {
            //对云对讲sip账号进行操作
            PropertySubscriberHanlerDTO subscriberHanlerDTO = new PropertySubscriberHanlerDTO(projectId, sn, sn, oldSn);
            JSONObject js = new JSONObject();
            js.put("data",subscriberHanlerDTO);
            messageSender.send(RabbitMQConstant.RABBITMQ_SAVE_OR_UPDATE_SIP_QUEUE, JsonUtil.toJSON(js),
                    RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,RabbitMQConstant.RABBITMQ_SAVE_OR_UPDATE_SIP_KEY);
        }
        //设备地址发生变化，更新服务地址表，推送云对讲重启指令
        if (deviceAddrPO != null || updateAddr) {

            //更新云对讲归属信息表
            String unitIds = propertyEquipSaveDTO.getUnitIds();
            String buildIds = propertyEquipSaveDTO.getBuildIds();
            List<Map<String, Object>> equipAddrList = new ArrayList<>();
            if (StringUtils.isNotEmpty(unitIds) && PropertyEquipTypeEnum.CLOUD_INTERCOM_ENTRANCE.getType() == propertyEquipSaveDTO.getSmartType()) {
                //云对讲归属于一栋多单元，门口机
                String[] unitIdArr = unitIds.split(",");
                for (String unitId : unitIdArr) {
                    DeviceCloudIntercomBridgeInfoPO dcciniPO = new DeviceCloudIntercomBridgeInfoPO(deviceUnique,
                            projectId, buildIds, unitId);
                    dcciniPO.setCreateTime(currentTime);
                    Map<String, Object> map = SqlUtil.durableData(dcciniPO, PlatformConstants.TABLE_SAVE);
                    equipAddrList.add(map);
                }
            } else {
                if (StringUtils.isNotEmpty(buildIds)) {
                    //云对讲归属于多栋，根据门口机和围墙机分别处理
                    String[] buildIdArr = buildIds.split(",");
                    for (String buildId : buildIdArr) {
                        DeviceCloudIntercomBridgeInfoPO dcciniPO = new DeviceCloudIntercomBridgeInfoPO(deviceUnique,
                                projectId, buildId, null);
                        dcciniPO.setCreateTime(currentTime);
                        Map<String, Object> map = SqlUtil.durableData(dcciniPO, PlatformConstants.TABLE_SAVE);
                        equipAddrList.add(map);
                    }
                }
            }

            if (!equipAddrList.isEmpty()) {
                iDeviceCloudIntercomBridgeInfoDao.batchSave(equipAddrList);
            }
            if (!delIdList.isEmpty()) {
                iDeviceCloudIntercomBridgeInfoDao.batchDeleteById(delIdList);
            }

            // 地址变化，推送云对讲重启指令
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("deviceUnique", deviceUnique);
            jsonObject.put("projectId", projectId);
            jsonObject.put("sn", sn);
            deviceBusinessChangeLogPOS.add(new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_DEVICE_ONE, jsonObject, projectId));
        }

        //设备名称发生变化时，推送设备云对讲拉取基础信息指令
        if (!(oldCloudIntercom.getDeviceName()).equals(deviceCloudIntercomInfoPO.getDeviceName()) && deviceBusinessChangeLogPOS.isEmpty()) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("deviceUnique", deviceUnique);
            jsonObject.put("projectId", projectId);
            jsonObject.put("sn", sn);
            deviceBusinessChangeLogPOS.add(new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_DEVICE_ONE, jsonObject, projectId));
        }
        if (!oldCloudIntercom.getEquipMode().equals(deviceCloudIntercomInfoPO.getEquipMode()) && deviceBusinessChangeLogPOS.isEmpty()) {
            JSONArray jsonArray = new JSONArray();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("deviceUnique",deviceUnique);
            jsonArray.add(jsonObject);
            deviceBusinessChangeLogPOS.add(new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_DEVICE, jsonArray, projectId));
        }


        if(StringUtils.isNotEmpty(propertyEquipSaveDTO.getBatchNumber()) && (StringUtils.isEmpty(oldCloudIntercom.getBatchNumber()) ||
                (StringUtils.isNotEmpty(oldCloudIntercom.getBatchNumber()) && !propertyEquipSaveDTO.getBatchNumber().equals(oldCloudIntercom.getBatchNumber())))){
            JSONArray jsonArray = new JSONArray();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("deviceUnique", deviceUnique);
            jsonArray.add(jsonObject);
            deviceBusinessChangeLogPOS.add(new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_DEVICE, jsonArray, projectId));
        }

        //设备是否配置人脸识别发生变化时，推送设备云对讲拉取基础信息指令
        if (oldCloudIntercom.getIsFaceRecognition()!=deviceCloudIntercomInfoPO.getIsFaceRecognition()) {
            JSONArray jsonArray = new JSONArray();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("deviceUnique", deviceUnique);
            jsonArray.add(jsonObject);
            deviceBusinessChangeLogPOS.add(new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_DEVICE_FACE_INFO, jsonArray, projectId));
        }

        updateVO.setUpdateCount(saveCloudIntercom);

        return deviceBusinessChangeLogPOS;
    }

    /**
     * <desc>
     *       重置/修改电梯楼层映射表时，推送映射表信息给一卡通
     * <desc/>
     *
     * @param projectId        操作的所属项目ID
     * @param data             操作的电梯楼层映射表信息
     * @param operateEquipType 操作类型 添加或更新
     * @author Juguang.S
     * @createDate 2018/08/21
     */
    public void prepareEquipFloorRelationDataInfoForSyncToSmartCard(String projectId, String data, SmartCardSyncDataOperTypeEnum operateEquipType) throws Exception {
        //打包
        SmartCardSyncDataPullDTO smartCardSyncDataPullDTO = new SmartCardSyncDataPullDTO(projectId, data, operateEquipType,
                SmartCardSyncDataTypeEnum.FLOOR_RELATION_DATA);
        //发送
        JSONObject dataJs = new JSONObject();
        dataJs.put("data",JSONObject.toJSON(smartCardSyncDataPullDTO));
        messageSender.send(RabbitMQConstant.RABBITMQ_SMARTCARD_SAVE_MODIFY_QUEUE, JsonUtil.toJSON(dataJs),
                RabbitMQConstant.RABBITMQ_SMARTCARD_SAVE_EXCHANGE, RabbitMQConstant.RABBITMQ_SMARTCARD_SAVE_MODIFY_ROUTING_KEY);
    }


    /**
     * <desc>
     *       操作设备时，推送设备信息给一卡通
     * <desc/>
     *
     * @param projectId        操作的所属项目ID
     * @param data             操作的设备数据
     * @param operateEquipType 操作类型 添加或更新
     * @author Biao.R
     * @createDate 2017/11/25
     */
    public void prepareEquipInfoForSyncToSmartCard(String projectId, String data, SmartCardSyncDataOperTypeEnum operateEquipType) throws Exception {
        //打包
        SmartCardSyncDataPullDTO smartCardSyncDataPullDTO = new SmartCardSyncDataPullDTO(projectId, data, operateEquipType,
                SmartCardSyncDataTypeEnum.EQUIP_DATA);
        //发送
        JSONObject dataJs = new JSONObject();
        dataJs.put("data",JSONObject.toJSON(smartCardSyncDataPullDTO));
        messageSender.send(RabbitMQConstant.RABBITMQ_SMARTCARD_SAVE_MODIFY_QUEUE, JsonUtil.toJSON(dataJs),
                RabbitMQConstant.RABBITMQ_SMARTCARD_SAVE_EXCHANGE, RabbitMQConstant.RABBITMQ_SMARTCARD_SAVE_MODIFY_ROUTING_KEY);
    }

    /**
     * <desc>
     *      向设备推送设备云对讲指令
     * <desc/>
     *
     * @param   changeLogPOS     云对讲变更指令集合
     * @author Biao.R
     * @createDate 2017/12/1
     */
    public void pushCloudIntercom(List<DeviceBusinessChangeLogPO> changeLogPOS) throws Exception {
        // 添加硬件推送指令
        if (!changeLogPOS.isEmpty()) {
            JSONObject dataJs = new JSONObject();
            dataJs.put("data", changeLogPOS);
            //云对讲
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                    JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
        }
    }

    /**
     * <desc>
     *      向设备推送设备云电梯指令
     * <desc/>
     *
     * @param   changeLogPOS     云电梯变更指令集合
     * @author Jiaqi.X
     * @createDate 2017/12/1
     */
    public void pushElevator(List<DeviceBusinessElevatorChangeLogPO> changeLogPOS) throws Exception {
        // 添加硬件推送指令
        if (!changeLogPOS.isEmpty()) {
            JSONObject dataJs = new JSONObject();
            dataJs.put("data", changeLogPOS);
            //云电梯
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                    JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
        }
    }

    /**
     * <desc>
     *      向设备推送设备云门禁指令
     * <desc/>
     *
     * @param   changeLogPOS     云门禁变更指令集合
     * @author Juguang.S
     * @createDate 2019/02/27
     */
    public void pushEntrance(List<DeviceBusinessEntranceChangeLogPO> changeLogPOS) throws Exception {
        // 添加硬件推送指令
        if (!changeLogPOS.isEmpty()) {
            JSONObject dataJs = new JSONObject();
            dataJs.put("data", changeLogPOS);
            //云门禁
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                    JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY);
        }
    }

    /**
     * <desc>
     *      运营启用项目云对讲时，同步云对讲Sip到服务器
     * <desc/>
     * @param   projectId   启用云对讲的小区ID
     * @return
     * @author Biao.R
     * @createDate 2018/1/26
     */
    @Override
    public void syncEquipSipWhenEnableCloud(String projectId) {
        try {
            if (StringUtils.isEmpty(projectId)) {
                return;
            }
            List<DeviceCloudIntercomInfoPO> cloudIntercomInfoPOS = iDeviceCloudIntercomInfoDao.getCloudIntercomsByProjectId(projectId);
            if (cloudIntercomInfoPOS != null && !cloudIntercomInfoPOS.isEmpty()) {
                for (DeviceCloudIntercomInfoPO cloudIntercomInfoPO : cloudIntercomInfoPOS) {
                    String sn = cloudIntercomInfoPO.getSn();
                    if (StringUtils.isNotEmpty(sn)) {
                        String oldSip = cloudIntercomInfoPO.getSipAccount();
                        String oldSipPsd = cloudIntercomInfoPO.getSipPsd();
                        if (StringUtils.isEmpty(oldSip) || StringUtils.isEmpty(oldSipPsd) || !sn.equals(oldSip)) {
                            cloudIntercomInfoPO.setSipAccount(sn);
                            cloudIntercomInfoPO.setSipPsd(sn);
                            cloudIntercomInfoPO.setUpdateTime(new Date());
                            iDeviceCloudIntercomInfoDao.update(SqlUtil.durableData(cloudIntercomInfoPO, PlatformConstants.TABLE_UPDATE));
                        }
                        //Sip刷新
                        PropertySubscriberHanlerDTO subscriberHanlerDTO = new PropertySubscriberHanlerDTO(projectId, sn, sn, oldSip);
                        JSONObject js = new JSONObject();
                        js.put("data",subscriberHanlerDTO);
                        messageSender.send(RabbitMQConstant.RABBITMQ_SAVE_OR_UPDATE_SIP_QUEUE, JsonUtil.toJSON(js), RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                                RabbitMQConstant.RABBITMQ_SAVE_OR_UPDATE_SIP_KEY);
                    }
                }
            }
        } catch (Exception e) {
            throw new DataAccessException("【运营启用项目云对讲】刷新设备Sip异常:", e);
        }
    }

    /**
     * <desc>
     *      处理设备旧数据的sip账号，为了便于灵云区分测试和正式sip故在测试环境设备账号前加184前缀
     * <desc/>
     *
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2018/12/28
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateOldDeviceSipAccount() throws Exception {
         //获取修改后的所有设备sip账号
         List<Map<String,String>> list = iDeviceCloudIntercomInfoDao.getDeviceSipAccount();
         List<DeviceBusinessChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
         for(Map<String,String> map : list){
             String projectId = map.get("projectId");
             String sipAccount = map.get("sipAccount");
             String sipPsd = map.get("sipPsd");
             String deviceUnique = map.get("deviceUnique");
             //保存sip信息
             PropertySubscriberHanlerDTO subscriberHanlerDTO = new PropertySubscriberHanlerDTO(projectId,sipAccount, sipPsd,null);
             JSONObject js = new JSONObject();
             js.put("data",subscriberHanlerDTO);
             messageSender.send(RabbitMQConstant.RABBITMQ_SAVE_OR_UPDATE_SIP_QUEUE, JsonUtil.toJSON(js), RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE,
                     RabbitMQConstant.RABBITMQ_SAVE_OR_UPDATE_SIP_KEY);

             //推送设备云对讲重启指令
             JSONObject jsonObject = new JSONObject();
             jsonObject.put("projectId", projectId);
             jsonObject.put("deviceUnique", deviceUnique);
             jsonObject.put("sn", sipPsd);
             deviceBusinessChangeLogPOS.add(new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_DEVICE_ONE, jsonObject, projectId));
         }
         // 推送云对讲、云电梯重启指令
         if (deviceBusinessChangeLogPOS != null && !deviceBusinessChangeLogPOS.isEmpty()) {
             this.pushCloudIntercom(deviceBusinessChangeLogPOS);
         }
    }

}